/**
* Copyright (c) 2011 Martin M Reed
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.hardisonbrewing.signingserver.service.icon;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.m2g.SVGImage;
import net.hardisonbrewing.signingserver.SigservApplication;
import net.hardisonbrewing.signingserver.service.store.push.PushPPGStatusStore;
import net.hardisonbrewing.signingserver.service.store.push.PushSIGStatusStore;
import net.hardisonbrewing.signingserver.service.store.sig.SigStatusStore;
import net.rim.blackberry.api.homescreen.HomeScreen;
import net.rim.blackberry.api.messagelist.ApplicationIcon;
import net.rim.blackberry.api.messagelist.ApplicationIndicator;
import net.rim.blackberry.api.messagelist.ApplicationIndicatorRegistry;
import net.rim.blackberry.api.push.PushApplicationStatus;
import net.rim.device.api.system.ApplicationDescriptor;
import net.rim.device.api.system.ApplicationManager;
import net.rim.device.api.system.ApplicationManagerException;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.CodeModuleManager;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.XYDimension;
import net.rim.device.api.ui.XYEdges;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.NodeList;
import org.w3c.dom.svg.SVGElement;
import org.w3c.dom.svg.SVGSVGElement;
public class IconService extends IconServicePlatform {
private static final Logger log = LoggerFactory.getLogger( IconService.class );
public static void updateIcon() {
Hashtable sigStatus = SigStatusStore.get();
if ( sigStatus == null || sigStatus.isEmpty() ) {
updateIcon( Icons.COLOR_UNKNOWN, false );
return;
}
if ( !SigStatusStore.isSuccess() ) {
updateIcon( Icons.COLOR_FAILURE, true );
return;
}
updateIcon( Icons.COLOR_SUCCESS, false );
}
private static ApplicationIndicator getApplicationIndicator() {
ApplicationIndicatorRegistry applicationIndicatorRegistry = ApplicationIndicatorRegistry.getInstance();
ApplicationIndicator applicationIndicator = applicationIndicatorRegistry.getApplicationIndicator();
if ( applicationIndicator != null ) {
return applicationIndicator;
}
SVGImage svgImage = SVGService.getImage( Icons.LOGO_URL );
int dimension = Icons.APPLICATION_INDICATOR_SIZE;
do {
ApplicationIcon applicationIcon = getApplicationIcon( svgImage, dimension );
try {
// this may throw an exception is the byte[] length is over 1k or so
// even if the image size is 64x64 pixels
applicationIndicator = applicationIndicatorRegistry.register( applicationIcon, true, false );
}
catch (IllegalArgumentException e) {
dimension = (int) Math.floor( dimension * 0.80 );
continue;
}
}
while (applicationIndicator == null && dimension > 0);
if ( applicationIndicator == null ) {
throw new IllegalStateException( "Unable to create a new ApplicationIcon." );
}
return applicationIndicator;
}
private static ApplicationIcon getApplicationIcon( SVGImage svgImage, int size ) {
XYDimension image = new XYDimension( size, size );
changeColor( svgImage, Icons.COLOR_FAILURE );
EncodedImage encodedImage = SVGService.convert( svgImage, image, null );
return new ApplicationIcon( encodedImage );
}
public static void setIndicatorVisible( boolean visible ) {
ApplicationIndicator applicationIndicator = getApplicationIndicator();
applicationIndicator.setVisible( visible );
}
public static void setIconNewState( boolean newState ) {
ApplicationDescriptor[] applicationDescriptors = getVisibleApplicationDescriptors();
for (int i = 0; i < applicationDescriptors.length; i++) {
ApplicationDescriptor applicationDescriptor = applicationDescriptors[i];
ApplicationManager applicationManager = ApplicationManager.getApplicationManager();
if ( applicationManager.getProcessId( applicationDescriptor ) != -1 ) {
IconService.setIconNewState( newState, applicationDescriptor );
continue;
}
String[] startupArguments = { SigservApplication.UPDATE_ICON_STATE, String.valueOf( newState ) };
ApplicationDescriptor updateApplicationDescriptor = new ApplicationDescriptor( applicationDescriptor, startupArguments );
try {
applicationManager.runApplication( updateApplicationDescriptor );
}
catch (ApplicationManagerException e) {
log.error( "Unable to update icon state" );
}
}
}
public static void updateIcon( String color, boolean indicatorVisible ) {
setIndicatorVisible( indicatorVisible );
updateIcon( color );
}
public static Bitmap getPreferredIcon( String color ) {
int width = HomeScreen.getPreferredIconWidth();
int height = HomeScreen.getPreferredIconHeight();
XYDimension image = new XYDimension( width, height );
XYEdges padding = new XYEdges( 10, 10, 10, 10 );
EncodedImage encodedImage = getImage( Icons.LOGO_URL, image, padding, color );
return encodedImage.getBitmap();
}
public static void updateIcon( String color ) {
Bitmap bitmap = getPreferredIcon( color );
ApplicationDescriptor[] applicationDescriptors = getVisibleApplicationDescriptors();
for (int i = 0; i < applicationDescriptors.length; i++) {
ApplicationDescriptor applicationDescriptor = applicationDescriptors[i];
ApplicationManager applicationManager = ApplicationManager.getApplicationManager();
if ( applicationManager.getProcessId( applicationDescriptor ) != -1 ) {
HomeScreen.updateIcon( bitmap, applicationDescriptor );
continue;
}
String[] startupArguments = { SigservApplication.UPDATE_ICON_BITMAP, color };
ApplicationDescriptor updateApplicationDescriptor = new ApplicationDescriptor( applicationDescriptor, startupArguments );
try {
applicationManager.runApplication( updateApplicationDescriptor );
}
catch (ApplicationManagerException e) {
log.error( "Unable to update icon bitmap" );
}
}
}
private static ApplicationDescriptor[] getVisibleApplicationDescriptors() {
ApplicationDescriptor currentApplicationDescriptor = ApplicationDescriptor.currentApplicationDescriptor();
ApplicationDescriptor[] applicationDescriptors = CodeModuleManager.getApplicationDescriptors( currentApplicationDescriptor.getModuleHandle() );
Vector results = new Vector();
for (int i = 0; i < applicationDescriptors.length; i++) {
ApplicationDescriptor applicationDescriptor = applicationDescriptors[i];
int flags = applicationDescriptor.getFlags();
if ( ( flags & ApplicationDescriptor.FLAG_SYSTEM ) == ApplicationDescriptor.FLAG_SYSTEM ) {
continue;
}
results.addElement( applicationDescriptor );
}
ApplicationDescriptor[] _results = new ApplicationDescriptor[results.size()];
results.copyInto( _results );
return _results;
}
public static EncodedImage getImage( String name, XYDimension image, XYEdges padding, String color ) {
SVGImage svgImage = SVGService.getImage( name );
changeColor( svgImage, color );
boolean pushPPGRegistered = PushPPGStatusStore.get() == PushApplicationStatus.STATUS_ACTIVE;
adjustPushColor( svgImage, 0, pushPPGRegistered, color, Icons.COLOR_UNKNOWN );
boolean pushSIGRegistered = PushSIGStatusStore.get();
adjustPushColor( svgImage, 1, pushSIGRegistered, color, Icons.COLOR_UNKNOWN );
return SVGService.convert( svgImage, image, padding );
}
private static void adjustPushColor( SVGImage svgImage, int index, boolean on, String onColor, String offColor ) {
SVGSVGElement svgElement = (SVGSVGElement) svgImage.getDocument().getDocumentElement();
NodeList paths = svgElement.getElementsByTagName( "path" );
SVGElement element = (SVGElement) paths.item( index );
element.setTrait( "fill", on ? onColor : offColor );
}
private static void changeColor( SVGImage svgImage, String color ) {
SVGSVGElement svgElement = (SVGSVGElement) svgImage.getDocument().getDocumentElement();
NodeList paths = svgElement.getElementsByTagName( "path" );
for (int i = 0; i < paths.getLength(); i++) {
SVGElement element = (SVGElement) paths.item( i );
element.setTrait( "fill", color );
}
}
}